package org.xnat.xnatfs.webdav;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.xnat.xnatfs.asset.IStringAsset;
import org.xnat.xnatfs.util.JSONUtils;

import com.bradmcevoy.http.Resource;

public class Search extends VirtualDirectory {
  private static final Logger logger = Logger.getLogger ( Search.class );

  HashMap<String, VirtualDirectory> myChildren = new HashMap<String, VirtualDirectory> ();

  public Search ( XNATFS x, String path, String name, String url ) {
    super ( x, path, name, url );
  }

  @Override
  public VirtualResource child ( String childName ) {
    // Make sure we have our child list cached.
    getChildren ();
    if ( myChildren.get ( childName ) == null ) {
      logger.debug ( "null child: " + childName );
      return null;
    }
    logger.debug ( "Looking up " + childName + " returning " + myChildren.get ( childName ) );
    return myChildren.get ( childName );
  }

  @Override
  public List<? extends Resource> getChildren () {
    List<Resource> list = new ArrayList<Resource> ();

    myChildren.clear ();

    // Get the subjects code
    try {
      JSONObject json = JSONUtils.parseJSON ( (IStringAsset) retreiveAsset () );
      JSONArray results = json.getJSONObject ( "ResultSet" ).getJSONArray ( "Result" );
      logger.debug ( "Found: " + results.length () + " elements" );

      for ( int idx = 0; idx < results.length (); idx++ ) {
        JSONObject item = results.optJSONObject ( idx );
        if ( item == null ) {
          continue;
        }

        // If we have the keys session_id, project,
        // xnat_subjectdata_subjectid,
        // then we are a session
        if ( item.has ( "session_id" ) && item.has ( "project" ) && item.has ( "xnat_subjectdata_subjectid" ) ) {
          // Construct and add a child
          String projectName = item.getString ( "project" );
          String subjectID = item.getString ( "xnat_subjectdata_subjectid" );
          if ( item.has ( "xnat_subjectdata_subject_label" ) ) {
            subjectID = item.getString ( "xnat_subjectdata_subject_label" );
          }
          String sessionID = item.getString ( "session_id" );
          if ( item.has ( "label" ) ) {
            sessionID = item.getString ( "label" );
          }
          String name = projectName + "-" + subjectID + "-" + sessionID;
          // Need to construct the URL properly

          String experimentURL = "/projects/" + projectName + "/subjects/" + subjectID + "/experiments/" + sessionID + "/";
          Experiment exp = new Experiment ( xnatfs, absolutePath, name, experimentURL );
          myChildren.put ( name, exp );
        }
      }
    } catch ( Exception e ) {
      logger.warn ( "Caught exception processing " + getRestUrl (), e );
    }

    list.addAll ( myChildren.values () );
    Collections.sort ( list, new Comparator<Resource> () {
      public int compare ( Resource o1, Resource o2 ) {
        return o1.getName ().compareTo ( o2.getName () );
      }
    } );
    return list;
  }

  @Override
  protected String getRestUrl () {
    return mURL + "/results?format=json";
  }
}
